﻿/*
# -*- coding: utf-8 -*-
# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.

# 注意：

# 若希望将本代码用于商业用途，需先联系作者并获得明确授权。
# 作者不对因使用本代码引发的任何直接或间接损失负责。
# 如有违反上述条款的行为，作者保留追究法律责任的权利。

# 免责声明：
# 请尊重知识产权，遵循相关法律法规。

# Notice:
# If you wish to use this code for commercial purposes, you must contact the author and obtain explicit authorization.
# The author is not responsible for any direct or indirect losses caused by the use of this code.
# If any of the above terms are violated, the author reserves the right to pursue legal action.
# Disclaimer:
# Please respect intellectual property rights and comply with relevant laws and regulations.
*/
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using UnityEngine.UI;
using EventManager;

public class GameMgr : SingletonMonoBehaviour<GameMgr>
{
    [SerializeField]
    GameController gameController;

    int levelIndex;
    float timePlay;
    float timeCurrent;
    int scoreTotal;
    public int resetCount;


    int levelMax;
    Level currentLevel;

    int lifeCount = 3;
    MoveMode moveMode;
    LevelState levelState;




    void OnEnable()
    {
        this.RegisterListener(EventID.UpdateScore, (sender, param) => UpdateScore((int)param));
    }

    void OnDisable()
    {
        this.RemoveListener(EventID.UpdateScore, (sender, param) => UpdateScore((int)param));
    }


    void Reset()
    {
        scoreTotal = 0;
        resetCount = lifeCount;
    }

    public void PlayGameFromLevel()
    {
        Reset();
        PlayGame();
        //InterstitialAd.Instance.ShowAd();
    }

    public void ReplayGame()
    {
        Reset();
        PlayGame();
    }

    public void NextLevel()
    {
        MissionManager.Instance.NextLevel();
        PlayGameFromLevel();
    }


    public bool isPlay = false;

    void PlayGame()
    {
        GameDataMgr.Hint = 2;
        //AdAssistant.Instance.RequestFullScreen();
        UIManager.Instance.ShowPage("GamePage");
        currentLevel = MissionManager.Instance.GetCurrentLevelData();

        moveMode = (MoveMode)currentLevel.moveMode;
        levelIndex = currentLevel.ID;
        gameController.InitMap(this, currentLevel, moveMode);
        int timeScale = moveMode == MoveMode.Idle ? 2 : 3;

        timeCurrent = timePlay = currentLevel.width * currentLevel.height * timeScale;  //convert minute to second

        isPlay = true;

        this.PostEvent(EventID.UpdateLevel, (levelIndex + 1));
        this.PostEvent(EventID.UpdateHint, GameDataMgr.Hint);
        this.PostEvent(EventID.UpdateScore, scoreTotal);
        resetCount = lifeCount;

        this.PostEvent(EventID.UpdateResetCount, resetCount);

    }

    public void UpdateResetCount()
    {
        resetCount--;
        if (resetCount < 0)
        {
            LevelFailed(false);
            return;
        }
        this.PostEvent(EventID.UpdateResetCount, resetCount);
    }

    void Update()
    {
        if (isPlay)
        {
            timeCurrent -= Time.deltaTime;
            this.PostEvent(EventID.UpdateTime, timeCurrent / timePlay);
            if (timeCurrent <= 0)
                LevelFailed(true);
        }
    }



    public void UpdateScore(int score)
    {
        scoreTotal += score;
        if (GameDataMgr.HighScore < scoreTotal)
            GameDataMgr.HighScore = scoreTotal;
        this.PostEvent(EventID.UpdateScoreTotal, scoreTotal);

    }



    public void PauseGame()
    {
        UIManager.Instance.ShowPage("PausePage");
        isPlay = false;
    }

    public void ResumeGame()
    {
        UIManager.Instance.ShowPage("GamePage");
        isPlay = true;
    }

    public void LeveFinish()
    {
        isPlay = false;
        AudioManager.Instance.Shot("completed");
        //add score time
        float scoreScale = moveMode == MoveMode.Idle ? 1 : 1.5f;
        //float scoreScale = 1;
        scoreTotal += (int)(timeCurrent * 10f * scoreScale);

        this.PostEvent((int)EventID.UpdateScore, scoreTotal);

        LeaderBoardMgr.Instance.PostHighScoreToLeaderBoard(scoreTotal);


        levelState = GetLevelStateFromTime();
    

        MissionManager.Instance.FinishLevel();


        MissionManager.Instance.SaveLevelState(currentLevel.ID, currentLevel.MissionID, levelState);

       

        if (Random.Range(0, 99) > 0)
        {
            //AdAssistant.Instance.SetCallBackFullScreen(()=>{

                UIManager.Instance.ShowPage("LevelCompleted");
                LevelCompletePanel.Instance.SetData((currentLevel.ID + 1).ToString(), scoreTotal, levelState);
            //});

            //AdAssistant.Instance.ShowFullScreen();
        }
        else
        {
            UIManager.Instance.ShowPage("LevelCompleted");
            LevelCompletePanel.Instance.SetData((currentLevel.ID + 1).ToString(), scoreTotal, levelState);
        }

        if (MissionManager.Instance.isWin())
        {
            StartCoroutine(OnWin());
        }

    }

    /// <summary>
    /// Get levelstate from time play when finish
    /// </summary>
    /// <returns></returns>
    LevelState GetLevelStateFromTime()
    {
        LevelState result = LevelState.IsOpen;
        if (timeCurrent / timePlay >= 0.3f)
            result = LevelState.IsThreeStar;
        else if (timeCurrent / timePlay >= 0.2f)
            result = LevelState.IsTwoStar;
        else if (timeCurrent / timePlay >= 0f)
            result = LevelState.IsOneStar;
        return result;
    }

    /// <summary>
    /// clear all levels
    /// </summary>
    /// <returns></returns>
    IEnumerator OnWin()
    {
        isPlay = false;
        yield return new WaitForSeconds(2f);
        UIManager.Instance.ShowPage("WinPage");
    }

    public void LevelFailed(bool isTimesup)
    {
        isPlay = false;
        AudioManager.Instance.Shot("failed");
        if (Random.Range(0, 99) > 50)
        {
            //AdAssistant.Instance.SetCallBackFullScreen(()=>{

                UIManager.Instance.ShowPage("LevelFailed");
                LevelFailedPanel.Instance.SetData((currentLevel.ID + 1).ToString(), scoreTotal, isTimesup);
                LeaderBoardMgr.Instance.PostHighScoreToLeaderBoard(scoreTotal);
            //});

            //AdAssistant.Instance.ShowFullScreen();
        }
        else
        {
            UIManager.Instance.ShowPage("LevelFailed");
            LevelFailedPanel.Instance.SetData((currentLevel.ID + 1).ToString(), scoreTotal, isTimesup);
            LeaderBoardMgr.Instance.PostHighScoreToLeaderBoard(scoreTotal);
        }
    }

}
